﻿using Microsoft.EntityFrameworkCore;
using mozhi.smarterp.Finance.Accounts;
using mozhi.smarterp.Finance.Banks;
using mozhi.smarterp.Finance.Basedatas;
using mozhi.smarterp.Finance.DataDicts;
using mozhi.smarterp.Finance.Documents;
using mozhi.smarterp.Finance.Files;
using mozhi.smarterp.Finance.Finances;
using mozhi.smarterp.Finance.Logs;
using mozhi.smarterp.Finance.Reports;
using mozhi.smarterp.Finance.Treasuries;
using mozhi.smarterp.Finance.Treasuries.Payments;
using mozhi.smarterp.Finance.Views;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;

namespace mozhi.smarterp.Finance.EntityFrameworkCore;

public static class FinanceDbContextModelCreatingExtensions
{
    public static void ConfigureFinance(
        this ModelBuilder builder)
    {
        Check.NotNull(builder, nameof(builder));

        /* Configure all entities here. Example:

        builder.Entity<Question>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "Questions", FinanceDbProperties.DbSchema);

            b.ConfigureByConvention();

            //Properties
            b.Property(q => q.Title).IsRequired().HasMaxLength(QuestionConsts.MaxTitleLength);

            //Relations
            b.HasMany(question => question.Tags).WithOne().HasForeignKey(qt => qt.QuestionId);

            //Indexes
            b.HasIndex(q => q.CreationTime);
        });
        */
        builder.Entity<Tag>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "Tag", FinanceDbProperties.DbSchema);

            b.ConfigureByConvention();

            //Properties
            b.Property(q => q.Name).IsRequired().HasMaxLength(100);
            b.HasIndex(x => new { x.Code, x.TenantId }).IsUnique();
            //Indexes
            b.HasIndex(q => q.CreationTime);
        });

        builder.Entity<TagItem>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "TagItem", FinanceDbProperties.DbSchema);

            b.ConfigureByConvention();

            //Properties
            b.Property(q => q.Name).IsRequired().HasMaxLength(100);
            b.HasIndex(x => new { x.Code, x.TenantId }).IsUnique();
            //Indexes
            b.HasIndex(q => q.CreationTime);
        });

        

        builder.Entity<Account>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "Account",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.Code, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<AccountDimensionItem>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "AccountDimensionItem",  FinanceDbProperties.DbSchema);
            b.Ignore(x => x.DimensionName);
            b.HasIndex(x => new { x.AccountId, x.DimensionId, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<vDefaultAccount>().HasNoKey().ToView("vDefaultAccount");

        builder.Entity<AccountDimension>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "AccountDimension",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.Code, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<BankAccount>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "BankAccount",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.Name, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<BankType>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "BankType",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.Name, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<DataAssociation>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "DataAssociation",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.OccupantId, x.OccupiedId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<AccountBalance>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "AccountBalance",  FinanceDbProperties.DbSchema);
            b.Property(x => x.OpeningAmount).HasColumnType("decimal(18,2)");
            b.Property(x => x.OpeningAmountFr).HasColumnType("decimal(18,2)");
            b.Property(x => x.DebitAmount).HasColumnType("decimal(18,2)");
            b.Property(x => x.DebitAmountFr).HasColumnType("decimal(18,2)");
            b.Property(x => x.CreditAmount).HasColumnType("decimal(18,2)");
            b.Property(x => x.CreditAmountFr).HasColumnType("decimal(18,2)");
            b.Property(x => x.CurrentYearDebitAmount).HasColumnType("decimal(18,2)");
            b.Property(x => x.CurrentYearDebitAmountFr).HasColumnType("decimal(18,2)");
            b.Property(x => x.CurrentYearCreditAmount).HasColumnType("decimal(18,2)");
            b.Property(x => x.CurrentYearCreditAmountFr).HasColumnType("decimal(18,2)");
            b.Property(x => x.ClosingAmount).HasColumnType("decimal(18,2)");
            b.Property(x => x.ClosingAmountFr).HasColumnType("decimal(18,2)");
            b.HasIndex(x => new { x.AccountId, x.CurrencyId, x.Period, x.DimensionGroupValueId, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<DimensionGroupValue>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "DimensionGroupValue",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.UniqueValue, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<DimensionGroupValueItem>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "DimensionGroupValueItem",  FinanceDbProperties.DbSchema);
            b.Ignore(x => x.Label);
            b.HasIndex(x => new { x.DimensionGroupValueId, x.DataSourceType, x.TagId, x.Value, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<Settlement>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "Settlement",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.Period, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<Journal>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "Journal",  FinanceDbProperties.DbSchema);
            b.Property(x => x.Period).IsRequired();
            b.Property(x => x.TotalAmount).IsRequired();
            b.Property(x => x.NumberPrefixId).IsRequired();
            b.Property(x => x.Number).IsRequired();
            b.Property(x => x.TotalAmount).HasColumnType("decimal(18,2)");
            b.HasIndex(x => new { x.NumberPrefixId, x.Number, x.Period, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<JournalItem>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "JournalItem",  FinanceDbProperties.DbSchema);
            b.Property(x => x.ExchangeRate).IsRequired();
            b.Property(x => x.CurrencyId).IsRequired();
            b.Property(x => x.Summary).IsRequired();
            b.Property(x => x.Amount).IsRequired();
            b.Property(x => x.ExchangeRate).HasColumnType("decimal(18,2)");
            b.Property(x => x.Amount).HasColumnType("decimal(18,2)");
            b.Property(x => x.CreditAmount).HasColumnType("decimal(18,2)");
            b.Property(x => x.DebitAmount).HasColumnType("decimal(18,2)");
            b.ConfigureByConvention();
        });

        builder.Entity<JournalNumberPrefix>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "JournalNumberPrefix",  FinanceDbProperties.DbSchema);
            b.Property(x => x.Code).IsRequired();
            b.Property(x => x.Name).IsRequired();
            b.HasIndex(x => new { x.Name, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        //builder.Entity<JournalTemplate>(b =>
        //{
        //    b.ToTable(FinanceDbProperties.DbTablePrefix + "JournalTemplate",  FinanceDbProperties.DbSchema);
        //    b.Property(x => x.Code).IsRequired();
        //    b.Property(x => x.Name).IsRequired();
        //    b.HasIndex(x => new { x.Code, x.TenantId }).IsUnique();
        //    b.ConfigureByConvention();
        //});

        //builder.Entity<JournalTemplateItem>(b =>
        //{
        //    //Configure table & schema name
        //    b.ToTable(FinanceDbProperties.DbTablePrefix + "JournalTemplateItem",  FinanceDbProperties.DbSchema);
        //    b.Property(x => x.ExchangeRate).IsRequired();
        //    b.Property(x => x.CurrencyId).IsRequired();
        //    b.Property(x => x.Summary).IsRequired();
        //    b.Property(x => x.Amount).IsRequired();
        //    b.Property(x => x.ExchangeRate).HasColumnType("decimal(18,2)");
        //    b.Property(x => x.Amount).HasColumnType("decimal(18,2)");
        //    b.Property(x => x.CreditAmount).HasColumnType("decimal(18,2)");
        //    b.Property(x => x.DebitAmount).HasColumnType("decimal(18,2)");
        //    b.ConfigureByConvention();
        //});

        builder.Entity<EndPeriodProcessItem>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "EndPeriodProcessItem",  FinanceDbProperties.DbSchema);
            b.Property(x => x.Name).IsRequired();
            b.HasIndex(x => new { x.Name, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<EndPeriodProcessItemSetting>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "EndPeriodProcessItemSetting",  FinanceDbProperties.DbSchema);
            b.Property(x => x.Name).IsRequired();
            b.HasIndex(x => new { x.EndPeriodProcessItemId, x.Name, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<EndPeriodProcessResult>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "EndPeriodProcessResult",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.ItemId, x.Period, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<EndPeriodProcessResultItem>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "EndPeriodProcessResultItem",  FinanceDbProperties.DbSchema);
            b.Property(x => x.Name).IsRequired();
            b.HasIndex(x => new { x.EndPeriodProcessResultId, x.Name, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<Payment>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "Payment",  FinanceDbProperties.DbSchema);
            b.Property(x => x.Number).IsRequired();
            b.Property(x => x.ExchangeRate).IsRequired();
            b.Property(x => x.CurrencyId).IsRequired();
            b.Property(x => x.Amount).IsRequired();
            b.Property(x => x.AmountFr).IsRequired();
            b.Property(x => x.ExchangeRate).HasColumnType("decimal(18,2)");
            b.Property(x => x.Amount).HasColumnType("decimal(18,2)");
            b.Property(x => x.AmountFr).HasColumnType("decimal(18,2)");
            b.Ignore(x => x.Currency);
            b.ConfigureByConvention();
        });

        builder.Entity<PaymentItem>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "PaymentItem",  FinanceDbProperties.DbSchema);
            b.Property(x => x.Amount).IsRequired();
            b.Property(x => x.AmountFr).IsRequired();
            b.Property(x => x.Amount).HasColumnType("decimal(18,2)");
            b.Property(x => x.AmountFr).HasColumnType("decimal(18,2)");
            b.Ignore(x => x.Product);
            b.Ignore(x => x.ExpenseItem);
            b.ConfigureByConvention();
        });

        builder.Entity<PaymentOrderLink>(b =>
        {
            //Configure table & schema name
            b.ToTable(FinanceDbProperties.DbTablePrefix + "PurchaseOrderAdvancePayment", FinanceDbProperties.DbSchema);
            b.Property(x => x.OrderId).IsRequired();
            b.Property(x => x.PaymentId).IsRequired();
            b.Property(x => x.OrderAmountFr).IsRequired();
            b.Property(x => x.AdvanceAmountFr).IsRequired();
            b.Property(x => x.AdvanceAmount).IsRequired();
            b.Property(x => x.OrderAmountFr).HasColumnType("decimal(18,2)");
            b.Property(x => x.AdvanceAmountFr).HasColumnType("decimal(18,2)");
            b.Property(x => x.AdvanceAmount).HasColumnType("decimal(18,2)");
            b.ConfigureByConvention();
        });

        builder.Entity<DocumentJournalRelationship>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "DocumentJournalRelationship",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.DocumentId, x.JournalId, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<FinancialReportItem>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "FinancialReportItem",  FinanceDbProperties.DbSchema);
            b.HasIndex(x => new { x.ReportType, x.Code, x.TenantId }).IsUnique();
            b.ConfigureByConvention();
        });

        builder.Entity<FinancialReportItemSetting>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "FinancialReportItemSetting",  FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();
        });

        builder.Entity<vFinancialReportItem>().HasNoKey().ToView("vFinancialReportItem");
        builder.Entity<vFinancialReportItemSetting>().HasNoKey().ToView("vFinancialReportItemSetting");

        builder.Entity<OperationLog>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "OperationLog",  FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();
        });

        builder.Entity<OperationLogItem>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "OperationLogItem",  FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();
        });

        builder.Entity<OperationLogSetting>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "OperationLogSetting",  FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();
        });

        builder.Entity<OperationSettingItem>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "OperationSettingItem",  FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();
        });

        builder.Entity<Attachment>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "Attachment",  FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();
        });

        builder.Entity<File>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "File",  FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();
        });

        builder.Entity<PrintTemplate>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "PrintTemplate",  FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();

        });

        builder.Entity<DataDictionary>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "DataDictionary",  FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();

        });

        builder.Entity<PaymentRequisition>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "PaymentRequisition", FinanceDbProperties.DbSchema);
            b.Ignore(x => x.Employee);
            b.Ignore(x => x.Supplier);
            b.Ignore(x => x.Customer);
            b.Ignore(x => x.Currency);
            b.ConfigureByConvention();
        });

        builder.Entity<PaymentRequisitionItem>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "PaymentRequisitionItem", FinanceDbProperties.DbSchema);
            b.Property(x => x.Amount).HasColumnType("decimal(18,2)");
            b.Property(x => x.AmountFr).HasColumnType("decimal(18,2)");
            b.Property(x => x.PayableAmount).HasColumnType("decimal(18,2)");
            b.Property(x => x.PayableAmountFr).HasColumnType("decimal(18,2)");
            b.ConfigureByConvention();
        });

        builder.Entity<PaymentRequisitionLink>(b =>
        {
            b.ToTable(FinanceDbProperties.DbTablePrefix + "PaymentRequisitionLink", FinanceDbProperties.DbSchema);
            b.ConfigureByConvention();
        });
    }
}
